/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.stores.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.entity.enums.PaymentState;
import com.qinyeit.serviceapp.entity.enums.ReceivePaymentType;
import com.qinyeit.serviceapp.entity.enums.StoreOutState;
import com.qinyeit.serviceapp.entity.enums.StoreOutType;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.repository.stores.StoreOutOrderDetailRepository;
import com.qinyeit.serviceapp.service.dishes.DishesStoreService;
import com.qinyeit.serviceapp.service.materials.MaterialService;
import com.qinyeit.serviceapp.service.stores.ReceivePaymentDetailService;
import com.qinyeit.serviceapp.service.stores.ReceivePaymentService;
import com.qinyeit.serviceapp.service.stores.StockService;
import com.qinyeit.serviceapp.utils.CompuUtils;
import com.qinyeit.serviceapp.utils.LocalUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.qinyetech.springstage.core.service.BaseService;
import com.qinyeit.serviceapp.repository.stores.StoreOutOrderRepository;
import com.qinyeit.serviceapp.service.stores.StoreOutOrderService;

import java.util.Date;
import java.util.List;

/** 
 * ClassName: StoreOutOrderServiceImpl <br/> 
 * Function: 出库单据 业务实现 <br/> 
 * date: 2018-11-08 14:02:01 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class StoreOutOrderServiceImpl extends BaseService<StoreOutOrder, Long> implements StoreOutOrderService {


	@Autowired
	private StoreOutOrderRepository storeOutOrderRepository;
	@Autowired
	private StoreOutOrderDetailRepository storeOutOrderDetailRepository;
	@Autowired
	private StockService stockService;
	@Autowired
	private DishesStoreService dishesStoreService;
	@Autowired
	private MaterialService materialService;
	@Autowired
	private ReceivePaymentService receivePaymentService;
	@Autowired
	private ReceivePaymentDetailService receivePaymentDetailService;


	@Override
	public void saveData(JSONObject data, Long merchantGroupId,String operator) {
		JSONObject orderData = data.getJSONObject("storeOutOrder");
		if(orderData==null){
			throw new BusinessRunTimeException("订单信息为空",10001);
		}

		if(orderData.getLong("supplierId")==null){
			throw new BusinessRunTimeException("请选择供应商",10002);
		}
		if (orderData.getLong("warehouseId")==null){
			throw new BusinessRunTimeException("请选择仓库",10003);
		}
		JSONArray detailData = data.getJSONArray("details");
		if(CollectionUtils.isEmpty(detailData)){
			throw new BusinessRunTimeException("单据明细为空",10004);
		}

		Long id = orderData.getLong("id");
		StoreOutOrder storeOutOrder = null;
		if(id==null){
			//保存
			storeOutOrder = new StoreOutOrder();
			storeOutOrder.setNo(LocalUtils.getOrderNo());
		}else {
			//编辑
			storeOutOrder = this.findById(id);
			//删除明细
			storeOutOrderRepository.deleteOrderDetails(id,merchantGroupId);
		}

		storeOutOrder.setSupplierId(orderData.getLong("supplierId"));
		storeOutOrder.setWarehouseId(orderData.getLong("warehouseId"));
		storeOutOrder.setSupplierName(orderData.getString("supplierName"));
		storeOutOrder.setWarehouseName(orderData.getString("warehouseName"));
		storeOutOrder.setOutTime(new Date());
		storeOutOrder.setRemark(orderData.getString("remark"));

		DishesStore dishesStore = dishesStoreService.findById(orderData.getLong("storeId"));
		storeOutOrder.setStoreId(orderData.getLong("storeId"));
		storeOutOrder.setStoreName(dishesStore.getName());
		int type = data.getInteger("type");
		if(type==1){
			//保存
			storeOutOrder.setState(StoreOutState.NOAUDIT);
			storeOutOrder.setOperator(null);
			storeOutOrder.setOperatorName(operator);
		}else if (type == 2){
			//提交并审核
			storeOutOrder.setState(StoreOutState.AUDIT);
			storeOutOrder.setChecker(null);
			storeOutOrder.setCheckerName(operator);
		}
		storeOutOrder.setPayAmount(orderData.getDouble("payAmount"));
		storeOutOrder.setGiftAmount(orderData.getDouble("giftAmount"));
		storeOutOrder.setType(StoreOutType.valueOf(orderData.getString("type")));
		double amountSum = 0.0;
		JSONObject item ;
		List<StoreOutOrderDetail> detailList = Lists.newArrayList();
		StoreOutOrderDetail detail = null;
		Material material = null;
		for (int i = 0; i < detailData.size(); i++) {
			item = detailData.getJSONObject(i);
			detail = new StoreOutOrderDetail();
			material = materialService.findById(item.getLong("materialId"));
			detail.setMaterialId(item.getLong("materialId"));
			detail.setName(item.getString("name"));
			detail.setCount(item.getDouble("count"));
			detail.setOrder(storeOutOrder);
			detail.setPrice(item.getDouble("price"));
			detail.setNo(item.getString("no"));
			detail.setSpec(item.getString("spec"));
			detail.setTotal(CompuUtils.multiply(item.getDouble("count"),item.getDouble("price")));
			detail.setMerchantGroupId(merchantGroupId);
			detail.setUnit(item.getString("unit"));
			detail.setRemark(item.getString("remark"));
			detail.setCreateAt(DateUtils.date());
			detail.setCode(material.getCode());
			detailList.add(detail);
			amountSum = CompuUtils.add(amountSum,detail.getTotal());
		}
		storeOutOrderDetailRepository.saveAll(detailList);
		storeOutOrder.setAmount(amountSum);
		storeOutOrder.setMerchantGroupId(merchantGroupId);

		storeOutOrder.setPayAmount(orderData.getDouble("payAmount"));
		storeOutOrder.setGiftAmount(orderData.getDouble("giftAmount"));
		double cha = CompuUtils.add(2,amountSum,orderData.getDouble("payAmount")*(-1),orderData.getDouble("giftAmount")*(-1));
		if(cha<0){
			throw new BusinessRunTimeException("实付金额不能大于订单总金额",10002);
		}
		if(cha==0){
			storeOutOrder.setPaymentState(PaymentState.SETTLED);
		}else {
			storeOutOrder.setPaymentState(PaymentState.NORMAL);
		}

		storeOutOrder = this.update(storeOutOrder);
		if(storeOutOrder.getState()==StoreOutState.AUDIT){
			//已审核 减去库存
			this.updateStock(storeOutOrder,detailList);
			//收款单 退货出库
			if(CompuUtils.compareTo(storeOutOrder.getPayAmount(),0)>0 && storeOutOrder.getType()==StoreOutType.STOREOUT){
				saveReceivePaymentOrders(storeOutOrder);
			}
		}
	}

	/**
	 * 总部出库 收款单
	 * @param storeOutOrder
	 * @param
	 */
	private void saveReceivePaymentOrders(StoreOutOrder storeOutOrder) {
		ReceivePayment payment = new ReceivePayment();
		payment.setRemark(storeOutOrder.getRemark());
		payment.setGiftAmount(storeOutOrder.getGiftAmount());
		payment.setAmount(storeOutOrder.getAmount());
		payment.setType(ReceivePaymentType.STOREIN);
		payment.setMerchantGroupId(storeOutOrder.getMerchantGroupId());
		payment.setOperatorName(storeOutOrder.getOperatorName());
		payment.setOperatorTime(DateUtils.date());
		payment.setSupplierName(storeOutOrder.getSupplierName());
		payment.setSupplierId(storeOutOrder.getSupplierId());
		payment.setNo(LocalUtils.getOrderNo());

		ReceivePaymentDetail detail = new ReceivePaymentDetail();
		detail.setRemark(storeOutOrder.getRemark());
		detail.setPaymentState(storeOutOrder.getPaymentState());
		detail.setGiftAmount(storeOutOrder.getGiftAmount());
		detail.setAmount(storeOutOrder.getPayAmount());
		detail.setOrderNo(storeOutOrder.getNo());
		detail.setOrder(payment);
		detail.setOrderAmount(storeOutOrder.getAmount());
		detail.setMerchantGroupId(storeOutOrder.getMerchantGroupId());

		payment = receivePaymentService.save(payment);
		receivePaymentDetailService.save(detail);
	}

	@Override
	public void updateStock(StoreOutOrder storeOutOrder, List<StoreOutOrderDetail> detailList){
		if (CollectionUtils.isEmpty(detailList)) {
			return ;
		}
		for (StoreOutOrderDetail detail : detailList) {
		  //查询库存
			Stock stock = stockService.getStocks(storeOutOrder.getWarehouseId(),detail.getMaterialId(),storeOutOrder.getMerchantGroupId());
			if(stock==null){
				return;
			}
			//出库不影响库存
			stock.setCount(CompuUtils.subtract(stock.getCount(),detail.getCount()));
			stock.setAmount(CompuUtils.multiply(stock.getCount(),stock.getCost()));
			stockService.update(stock);
		}
	}

}